<?php
class cat_tab extends tab {


    /**
     * 字段过滤规则
     *
     * @var unknown_type
     */
    public $filter = array(
        'name'      =>    array('filter' , 'text'),
        'ctype'     =>    'intval',
        'sort'      =>    'intval',
        'parent'    =>    'intval',
        'extra'     =>    'intval',
        'path'      =>    array('filter' , 'text'),
        'cover'     =>    array('filter' , 'text'),
        'sname'     =>    array('filter' , 'text'),
        'key'       =>    array('filter' , 'text'),
        'desc'      =>    array('filter' , 'text'),
    );


    public $validate = array(
        array(
            'key'   => 'name',
            'type'  => 0,
            'rule'  => 'require',
            'msg'   => '请输入类别名称!'
        ),
        array(
            'key'   => 'ctype',
            'type'  => 0,
            'rule'  => 'number',
            'msg'   => '分类类型格式错误'
        ),
        array(
            'key'   => 'parent',
            'type'  => 0,
            'rule'  => 'number',
            'msg'   => '请选择所属类别!'
        ),
        array(
            'key'   => 'parent',
            'type'  => 2,
            'rule'  => array('cat_tab' , 'vparent'),
            'msg'   => '类别所属不能为类别本身!'
        )
    );


    /**
     * 获取含所属关系的子类别列表
     *
     * @param unknown_type $parent
     * @param unknown_type $ctype
     * @param unknown_type $cascade 是否获取下属子类别
     * @return unknown
     */
    public function getlist($parent = 0 , $ctype = 0 , $cascade = false){
        $ret = array();
        if($cascade){
            $list = $this->fields('id,name,sname,path,sort,parent')->where("ctype = {$ctype} and instr(path , '#{$parent}#') ")->order('sort asc')->getall();
            if($list){
                $tmp = array();
                foreach ($list as $v){
                    $v['top'] = intval(substr($v['path'] , 3 ,1));
                    $tmp[(int)(substr_count($v['path'] , '#') - 2)][] = $v;;
                }
                $ret = array();
                for ($i = 0; $i < count($tmp); $i++){
                    foreach ($tmp[$i] as $sv){
                        $ret[$sv['id']] = $sv;
                    }
                }
                $out = $ret = array_reverse($ret , 1);
                foreach ($out as $k => $v){
                    if($v['parent'] > 0 && isset($out[$v['parent']])){
                        $ret[$v['parent']]['child'][$v['id']] =  $ret[$v['id']];
                        unset($ret[$k]);
                    }
                }
            }
        }else{
            $ret = $this->where("parent = {$parent} and ctype = {$ctype}")->order('sort desc , id asc')->getall();
        }
        return $ret;
    }

    /**
     * 获取简单关系的子类别列表
     *
     */
    public function getslist($parent = 0 ,$ctype = 0){
        $list = $this->getlist($parent , $ctype , 1);
        return $this->format($list);
    }

    /**
     * 验证类别的父类是否设置合理
     *
     * @param unknown_type $p
     * @param unknown_type $pk
     * @return unknown
     */
    public static function vparent($p , $pk){
        return $p != $pk || (int)$p === 0;
    }
    
    /**
     * 将有复杂的所属关系的数组转换成单一数组
     *
     * @param unknown_type $list
     * @return unknown
     */
    public function format(&$list){
        $ret = array();
        foreach ($list as $v){
            $v['last'] = (boolean)(isset($v['child']) && !empty($v['child']));
            if($v['last']){
                $child = $v['child'];
                unset($v['child']);
                $ret[$v['id']] = $v;
                $tmp = $this->format($child);
                foreach ($tmp as $tv){
                    $ret[$tv['id']] = $tv;
                }
            }else{
                $ret[$v['id']] = $v;
            }
        }
        return $ret;
    }
    
    /**
     * 更新子类别path字段
     *
     * @param unknown_type $ctype
     * @param unknown_type $path
     */
    public function refpath($ctype , $path , $npath){
        $list = $this->where("ctype = {$ctype} and instr(path , '{$path}') ")->getall();
        if($list){
            foreach ($list as $v){
                $this->where("id = {$v['id']}")
                     ->set('path' , str_replace($path , $npath , $v['path']))
                     ->set('parent',substr($v['path'] , -2 , 1))
                     ->save();
            }
        }
    }
}
?>